import React, { Component } from 'react'

class UserList extends Component {
  // constructor是ES6对类的默认方法，通过 new 命令生成对象实例时自动调用该方法。并且，该方法是类中必须有的，
  // 如果没有显示定义，则会默认添加空的constructor( )方法。
  constructor(props) {
    // 子类必须在constructor方法中调用super方法，否则新建实例时会报错。这是因为子类自己的this对象，
    // 必须先通过父类的构造函数完成塑造，得到与父类同样的实例属性和方法，然后再对其进行加工，
    // 加上子类自己的实例属性和方法。如果不调用super方法，子类就得不到this对象。
    super(props)
    console.log('constructor')
    // *****当你使用使用普通函数，必须把函数this指向到 UserList (不推荐使用这个方法)
    // this.handleClick = this.handleClick.bind(this)
    // 在这里设置数据，在其他地方调用该数据使用 this.state.time
    this.state = {
      name: 'Mark',
      Number: 1,
      time: '20190105 090522'
    }
  }

  // *****handleClick普通函数写法 (不推荐使用这个方法)
  // handleClick() {
  //   this.setState({ name: 'Zuck' })
  // }

  // handleClick 箭头函数写法，不用在 constructor(props)  里去指向this (推荐使用这个方法)
  handleClick = () => {
    // 修改数据，使用 this.setState() 方法
    this.setState({ name: 'Zuck' })
  }
  // 盗墓笔记测试接口 axios
  allList = () => {
    let data = `盗墓笔记`
    this.$http.post(`/novelSearchApi?name=${data}`).then(res => {
      console.log(res)
    })
  }
  // **挂载前**
  // 组件初始化时只调用，以后组件更新不调用，整个生命周期只调用一次，此时可以修改state。
  // 一般在这里更新数据，调用接口
  componentWillMount() {
    console.log('componentWillMount')
    let time = this.$moment(this.state.time).format('YYYY-MM-DD HH:mm:ss')
    console.log(time)
    this.allList()
  }
  // **挂载后**
  // 组件渲染之后调用，只调用一次。
  componentDidMount() {
    console.log('componentDidMount')
  }

  // **更新前**
  // 组件初始化时不调用，只有在组件将要更新时才调用，此时可以修改state
  componentWillUpdate(nextProps, nextState) {
    // console.log(nextProps,nextState)
    console.log('componentWillUpdate')
  }
  // **更新后**
  // 组件初始化时不调用，组件更新完成后调用，此时可以获取dom节点。
  componentDidUpdate() {
    console.log('componentDidUpdate')
  }
  // **销毁前**
  // 组件将要卸载时调用，一些事件监听和定时器需要在此时清除。
  componentWillUnmount() {
    console.log('componentWillUnmount')
  }
  // **判断组件是否应该重新渲染，默认是true**
  // react性能优化非常重要的一环。组件接受新的state或者props时调用，我们可以设置在此对比前后两个props和state是否相同，
  // 如果相同则返回false阻止更新，因为相同的属性状态一定会生成相同的dom树，这样就不需要创造新的dom树和旧的dom树进行diff算法对比，
  // 节省大量性能，尤其是在dom结构复杂的时候
  // shouldComponentUpdate函数是重渲染时render()函数调用前被调用的函数，它接受两个参数：nextProps和nextState，
  // 分别表示下一个props和下一个state的值。并且，当函数返回false时候，阻止接下来的render()函数的调用，阻止组件重渲染，而返回true时，组件照常重渲染。
  shouldComponentUpdate(nextProps, nextState) {
    // console.log(nextProps,nextState)
    console.log('shouldComponentUpdate')
    // 在render函数调用前判断：如果前后state中name不变，通过return false阻止render调用
    if (nextState.name === this.state.name) {
      return false
    } else {
      return true
    }
  }
  // 组件初始化时不调用，组件接受新的props时调用。
  componentWillReceiveProps() {
    console.log('componentWillReceiveProps')
  }
  // react最重要的步骤，创建虚拟dom，进行diff算法，更新dom树都在此进行。此时就不能更改state了。
  render() {
    return (
      <div>
        List
        <div onClick={this.handleClick}>Hi, {this.state.name}</div>
      </div>
    )
  }
}

export default UserList
